﻿using Lazy.Captcha.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using My.Admin.Dto.System;
using My.Admin.Model.System;
using My.Admin.Service.System;
using My.Admin.Service.System.IService;
using My.Admin.Util;
using My.Core.Attributes;
using My.Core.Cache;
using My.Core.CustomException;
using My.Core.Enums;
using My.Core.Extensions;
using My.Core.Filters;
using My.Core.Options;
using My.Core.Util;
using NewLife.Caching;
using System;
using System.ComponentModel;
using Yitter.IdGenerator;
using static Dm.net.buffer.ByteArrayBuffer;

namespace My.Admin.Controllers
{
    /// <summary>
    /// 登录相关
    /// </summary>
    [ApiController]
	[Route("[controller]")]
	public class LoginController : ControllerBase
	{
		private readonly ICaptcha _captcha;
		private readonly IUserService _UserService;
		private readonly ICache _cache;
		private readonly IHttpContextAccessor _httpContextAccessor;

		public LoginController(IHttpContextAccessor httpContextAccessor, ICaptcha captcha, IUserService UserService, ICache cache)
		{
			_captcha = captcha;
			_UserService = UserService;
			_cache = cache;
			_httpContextAccessor = httpContextAccessor;
		}

		/// <summary>
		/// 用户登录
		/// </summary>
		/// <param name="name"></param>
		/// <param name="pass"></param>
		/// <returns></returns>
		[HttpGet]
		[Route("Login")] // 路由地址规则
		[Log(Title = "登录")]
		public async Task<LoginOutput> Login(string name, string pass, string Code, string codeId)
		{
			// 从缓存中读取验证码并验证输入的验证码
			string CacheCode = CacheHelper.Get(codeId) as string;

			//string CacheCode1 = _cache.Get<string>(codeId);

			//if (CacheCode == null || !CacheCode.ToLower().Equals(Code.ToLower()))
			//{
			//	throw new CustomException(ResultCode.CAPTCHA_ERROR, "验证码错误", "验证码错误");
			//	//return "验证码错误";
			//}

			// 判断验证码
			if (!_captcha.Validate(codeId, Code))
				throw new CustomException(ResultCode.CAPTCHA_ERROR, "验证码错误", "验证码错误");


			User user = _UserService.Login(name, pass);
			if (user == null)
			{
				throw new CustomException(ResultCode.LOGIN_ERROR, "账号或密码错误", "账号或密码错误");
			}

			LoginUser loginUser = new LoginUser();
			loginUser.account = name;
			loginUser.id = 0;
			loginUser.password = pass;
			loginUser.username = name;
			// 测试 给固定的权限
			loginUser.Permissions = new List<string> { "system:weatherforecast:query" };

			return await CreateToken(loginUser);
			//return JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser), jwtSettings);
		}

		/// <summary>
		/// 获取验证码
		/// </summary>
		/// <returns></returns>
		[HttpGet]
		[Route("GetCaptcha")] // 路由地址规则
		[DisplayName("获取验证码")]
		public dynamic GetCaptcha()
		{
			var codeId = YitIdHelper.NextId().ToString();
			var captcha = _captcha.Generate(codeId);
			CacheHelper.SetCache(codeId, captcha.Code); // 将验证码保存到缓存中

			//_cache.Set(codeId, captcha.Code);

			string CacheCode = CacheHelper.Get(codeId) as string;
			return new { Id = codeId, Img = captcha.Base64 };
		}

		/// <summary>
		/// 生成Token令牌
		/// </summary>
		/// <param name="user"></param>
		/// <returns></returns>
		[NonAction]
		public async Task<LoginOutput> CreateToken(LoginUser user)
		{
			JwtSettings jwtSettings = new();
			AppSettings.Bind("JwtSettings", jwtSettings);

			// 生成Token令牌
			var accessToken = JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(user), jwtSettings);

			// 生成刷新Token令牌
			var refreshTokenExpire = jwtSettings.RefreshTokenTime;
			var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, refreshTokenExpire);

			// 设置响应报文头
			_httpContextAccessor.HttpContext.SetTokensOfResponseHeaders(accessToken, refreshToken);

			// Swagger Knife4UI-AfterScript登录脚本
			// ke.global.setAllHeader('Authorization', 'Bearer ' + ke.response.headers['access-token']);

			return new LoginOutput
			{
				AccessToken = accessToken,
				RefreshToken = refreshToken
			};
		}
	}
}
